package core.manager;

import java.util.Collection;
import java.util.concurrent.LinkedBlockingQueue;

import org.apache.log4j.Logger;

import core.descriptors.TaskDescriptor;
import core.util.COREServiceRegistry;

/**
 * La Classe Workflow permette di istanziare oggetti contenenti una collezione di Task.
 * Ogni volta che un utente (UI) sottomette dei Tasks, questi vengono inseriti in un Workflow.
 * Elemento caratterizzante di questa classe è quindi la lista (LinkedBlockingQueue) di Tasks.
  * @author Vincenzo Merlo, Scuderi Giovanni Luca, Paolo Giuffrida
 */
public class Workflow {

    private final Logger logger = COREServiceRegistry.getLogger(Workflow.class.toString());
    private Collection<TaskDescriptor> tasks;
    private int ID;

    /**
     * Costruttore. Viene istanziata la LinkedBlockingQueue di TaskDescriptor
     */
    public Workflow() {
        tasks = new LinkedBlockingQueue<TaskDescriptor>();
    }

    /**
     * Ritorna la lista dei Tasks
     * @return la lista (LinkedBlockingQueue) di tasks
     */
    public Collection<TaskDescriptor> getTasks() {
        return tasks;
    }

    /**
     * Setta la lista di Tasks
     * @param lista (LinkedBlockingQueue) di tasks
     */
    public void setTasks(Collection<TaskDescriptor> tasks) {
        this.setTasks(tasks);
    }

    /**
     * Ritorna l'id del Workflow
     * @return ID del Workflow
     */
    public int getID() {
        return ID;
    }

    /**
     * Inserisce un task descriptor nella lista
     * @param TaskDescriptor
     * @return posizione della lista nella quale viene inserito
     */
    public int addTask(TaskDescriptor task) {
        logger.trace("Add Task " + task);
         this.tasks.add(task);
        return (tasks.size() - 1);
    }

    /**
     * Ritorna l'elemento (TaskDescriptor) presente nella lista alla posizione specificata
     * @param int, indice della lista
     * @return TaskDescriptor
     */
    public TaskDescriptor getTask(int tid) {
        logger.trace(" getTask " + tid);
        try {
            return (TaskDescriptor)this.tasks.toArray()[tid];
        } catch (Exception e) {
            logger.error("getTask error : " + e.getStackTrace());
            return null;
        }
    }

    /**
     * Setta l'ID del WorkFlow
     * @param ID del Workflow da settare
     */
    public void setID(int ID) {
        logger.trace(" setID ");
        if (ID == 0) {
            this.ID = ID;
        } else {
            //TODO: Aggiugere Eccezione
            logger.error("Already ID was assigned");
        }
    }

    /**
     *
     * @return string
     */
    @Override
    public String toString() {
    	StringBuilder sb = new StringBuilder(Workflow.class.getSimpleName());
    	sb.append("\n\tID: ").append(this.getID());
        for (TaskDescriptor td: this.getTasks()) {
    		sb.append("\n\t").append(td);
    	}

    	return sb.toString();
    }

}
